package de.fhkl.gatav.ut.camera3touchthread;

import de.fhkl.gatav.ut.camera3touchthread.R;

import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.RectF;
import android.os.Bundle;
import android.util.FloatMath;
import android.util.Log;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnTouchListener;

public class CameraTouchThreadActivity extends Activity implements OnTouchListener {
	
	OurView v;
	Bitmap icon;
	TouchType touchState = TouchType.NONE;
	float scale;

    final static float MIN_DIST = 50;
    static float eventDistance = 0;
    static PointF center = new PointF( 0.0f, 0.0f );
    static PointF firstFingerPos = new PointF( 0.0f, 0.0f );
	
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        v = new OurView(this);
        v.setOnTouchListener(this);
        icon = BitmapFactory.decodeResource(getResources(), R.drawable.droid);
        firstFingerPos = new PointF(0.0f, 0.0f);
        center = new PointF( 0.0f, 0.0f );
        scale = 1.0f;
        setContentView(v);       
    }
    
    @Override
	protected void onPause() {
		v.pause();
		super.onPause();

	}

	@Override
	protected void onResume() {
		super.onResume();
		v.resume();
		}
	


    @Override
    public boolean onTouch(View v, MotionEvent event) {
    	int action = event.getAction();
    	
        switch (action & MotionEvent.ACTION_MASK) {
        case MotionEvent.ACTION_DOWN:
            //Primary touch event starts: remember touch down location
            touchState = TouchType.DRAG;
            firstFingerPos = new PointF( event.getX(0), event.getY(0));
            center.set(event.getX(0), event.getY(0));
            break;
            
        case MotionEvent.ACTION_POINTER_DOWN:
            //Secondary touch event starts: remember distance and center
            eventDistance = calcDistance(event);
            center = calcMidpoint(event);
            if (eventDistance > MIN_DIST) {
                touchState = TouchType.ZOOM;
                scale = 1.0f;      
            }
            break;
            
        case MotionEvent.ACTION_MOVE:
            if (touchState == TouchType.DRAG) {
                //Single finger drag, translate accordingly
                firstFingerPos = new PointF( event.getX(0), event.getY(0));
            } else if (touchState == TouchType.ZOOM) {
                //Double-finger zoom, scale accordingly around center
                float dist = calcDistance(event);
                if (dist > MIN_DIST) {
                    scale = dist / eventDistance;
                    firstFingerPos.set(center.x, center.y);
                }
            }
            break;
            
        case MotionEvent.ACTION_UP:
        	//Last finger up
            touchState = TouchType.NONE;
            break;
            
        case MotionEvent.ACTION_POINTER_UP:
        	//One of two fingers up
            touchState = TouchType.DRAG;
            //Update touch down location for drag event to holding finger
            final int pointerIndex = (action & MotionEvent.ACTION_POINTER_ID_MASK) >> MotionEvent.ACTION_POINTER_ID_SHIFT;
            switch (pointerIndex) {
            case 0:
                center = new PointF( event.getX(1), event.getY(1) );
                break;
            case 1:
                center = new PointF( event.getX(0), event.getY(0) );
                break;
            }
            break;
        }
        return true;
    }

    private float calcDistance(MotionEvent event) {
        float x = event.getX(0) - event.getX(1);
        float y = event.getY(0) - event.getY(1);
        return FloatMath.sqrt(x * x + y * y);
    }

    private PointF calcMidpoint(MotionEvent event) {
        return new PointF( (event.getX(0) + event.getX(1)) / 2, (event.getY(0) + event.getY(1)) / 2);
    }
	
	
	
	
	

	public class OurView extends SurfaceView implements Runnable {
    	
		Thread t = null;
		SurfaceHolder sh;
		boolean isThreadRunning = false;
		
    	public OurView(Context context) {
    		super(context);
    		sh = getHolder();
		}
    	
    	public void run() {
    		Rect nullRect = null;
    		Paint nullPaint = null;
    		
    		while (isThreadRunning) {
    			//perform some drawing
    			if (!sh.getSurface().isValid()) {
    				continue; //next loop
    			}
    			Canvas c = sh.lockCanvas(); //now we can paint to the canvas
    			c.drawARGB(255, 150, 150, 10);
    			c.drawBitmap(icon, nullRect, new RectF(firstFingerPos.x-(icon.getWidth()/2)*scale, firstFingerPos.y-(icon.getHeight()/2)*scale, 
    												   firstFingerPos.x+(icon.getWidth()/2)*scale, firstFingerPos.y+(icon.getHeight()/2)*scale),
    						 nullPaint);
       			Log.d(getLocalClassName() + "x,y,scale: ", Float.toString( firstFingerPos.x ) + " " + Float.toString( firstFingerPos.y ) + " " + Float.toString( scale ));
    			
    			sh.unlockCanvasAndPost(c);
    				
    		}
    	};
    	
    	public void pause() {
    		isThreadRunning = false;
    		while (true){
    			try {
    				t.join();
    			} catch (InterruptedException e) {
    				e.printStackTrace();
    			}
    			break;
    		}
    	};
    	
    	public void resume() {
    		isThreadRunning = true;
    		t = new Thread(this);
    		t.start();
    	};
    }


}